﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AddIn.EA.Framework;

namespace AddIn.EA.Architecture.ComponentLogic
{
    public class ProcessObjects
    {
        public ProcessObjects()
        {
            this.CreateProcessEntity = false;
            this.CreateProcessLogic = true;
            this.CreateResourceAccess = true;
        }

        public string Name { get; set; }
        public string IntelligenceModule { get; set; }
        public bool CreateProcessEntity { get; set; }
        public bool CreateProcessLogic { get; set; }
        public bool CreateResourceAccess { get; set; }

        public bool UpdateEA(Package generalProcessPackage)
        {
            try
            {
                CreateProcessClient(generalProcessPackage);

                CreateCatalog(generalProcessPackage);

                if (this.CreateProcessEntity)
                    CreateProcessEntityElement(generalProcessPackage);

                CreateProcessImplementation(generalProcessPackage);

                if (this.CreateProcessLogic)
                    CreateProcessLogicElement(generalProcessPackage);

                if (this.CreateResourceAccess)
                    CreateResourceAccessElement(generalProcessPackage);
            }
            catch
            {
                return false;
            }

            return true;
        }

        //*****
        private void CreateProcessClient(Package generalProcessPackage)
        {
            Package processClientPackage = generalProcessPackage.GetPackageByName("Client", true);

            Element processClient = processClientPackage.Elements.GetReferenceByName(this.Name);
            if (processClient == null)
                processClient = processClientPackage.Elements.AddNew(this.Name, ElementType.Class);

            processClient.Stereotype = "ProcessClient";
            processClient.Update();

            processClient.AddBaseClass("SinacorBaseProcessClient");
        }

        private void CreateCatalog(Package generalProcessPackage)
        {
            Package catalogPackage = generalProcessPackage.GetPackageByName("ProcessEntity", true).GetPackageByName("Catalog");

            Element catalog = catalogPackage.Elements.GetReferenceByName(this.Name);
            if (catalog == null)
                catalog = catalogPackage.Elements.AddNew(this.Name, ElementType.Class);

            catalog.Stereotype = "Catalog";
            catalog.Update();

            AttributeClass processID = catalog.Attributes.GetReferenceByName("ProcessID");
            if (processID == null)
                processID = catalog.Attributes.AddNew("ProcessID", "int");

            processID.InitialValue = "0";
            processID.IsConst = true;
            processID.Scope = ElementScope.Public;
            processID.Update();
        }

        private void CreateProcessEntityElement(Package generalProcessPackage)
        {
            Package processEntityPackage = generalProcessPackage.GetPackageByName("ProcessEntity", true);

            Element processEntity = processEntityPackage.Elements.GetReferenceByName(this.Name);
            if (processEntity == null)
                processEntity = processEntityPackage.Elements.AddNew(this.Name, ElementType.Class);

            processEntity.Stereotype = "ProcessEntity";
            processEntity.Update();

            CreateProcessEntityParameter(processEntityPackage);
        }

        private void CreateProcessEntityParameter(Package processEntityPackage)
        {
            Package processEntityParameterPackage = processEntityPackage.GetPackageByName("Parameter");

            string processEntityParameterName = string.Format("Filtro{0}", this.Name);
            Element processEntityParameter = processEntityParameterPackage.Elements.GetReferenceByName(processEntityParameterName);
            if (processEntityParameter == null)
                processEntityParameter = processEntityParameterPackage.Elements.AddNew(processEntityParameterName, ElementType.Class);

            processEntityParameter.Stereotype = "ProcessEntity";
            processEntityParameter.Update();
        }

        private void CreateProcessImplementation(Package generalProcessPackage)
        {
            Package processImplementationPackage = generalProcessPackage.GetPackageByName("Server", true).GetPackageByName("ProcessImplementation");

            Element processImplementation = processImplementationPackage.Elements.GetReferenceByName(this.Name);
            if (processImplementation == null)
                processImplementation = processImplementationPackage.Elements.AddNew(this.Name, ElementType.Class);

            processImplementation.Stereotype = "ProcessImplementation";
            processImplementation.Update();

            string baseClass = "SinacorBaseProcessServer";
            if(this.CreateProcessLogic)
                baseClass += string.Format("<ProcessLogic.{0}>", this.Name);

            processImplementation.AddBaseClass(baseClass);
            processImplementation.AddImplementedInterfaces(this.IntelligenceModule);
        }

        private void CreateProcessLogicElement(Package generalProcessPackage)
        {
            Package processLogicPackage = generalProcessPackage.GetPackageByName("Server", true).GetPackageByName("ProcessLogic");

            Element processLogic = processLogicPackage.Elements.GetReferenceByName(this.Name);
            if (processLogic == null)
                processLogic = processLogicPackage.Elements.AddNew(this.Name, ElementType.Class);

            processLogic.Stereotype = "ProcessLogic";
            processLogic.Update();

            processLogic.AddBaseClass("BaseProcessLogic");
        }

        private void CreateResourceAccessElement(Package generalProcessPackage)
        {
            Package resourceAccessPackage = generalProcessPackage.GetPackageByName("Server", true).GetPackageByName("ResourceAccess");

            Element resourceAccess = resourceAccessPackage.Elements.GetReferenceByName(this.Name);
            if (resourceAccess == null)
                resourceAccess = resourceAccessPackage.Elements.AddNew(this.Name, ElementType.Class);

            resourceAccess.Stereotype = "ResourceAccess";
            resourceAccess.Update();

            resourceAccess.AddBaseClass("BaseResourceAccess");
        }
    }
}
